import axios, { type AxiosInstance } from 'axios'
import router from '@/router'
import { useAuthorizationStore } from '@/service/AuthorizationService'
import { fetchEventSource } from '@microsoft/fetch-event-source'

export class BackendService {
  private client: AxiosInstance | undefined

  private baseURL: string

  constructor(baseURL: string) {
    this.baseURL = baseURL
    this.client = axios.create({
      baseURL: baseURL
    })

    this.client.interceptors.request.use(
      (config) => {
        config.headers['Authorization'] = `Bearer ${useAuthorizationStore().token}`
        return config
      },
      (error: any) => {
        return Promise.reject(error)
      }
    )

    this.client.interceptors.response.use(
      function (response) {
        return response
      },
      function (error) {
        const response = error.response
        if (response) {
          if (response.status === 401) {
            router.push({ path: '/login' }).finally()
            return Promise.reject(error)
          }
        }
        return Promise.reject(error)
      }
    )
  }

  public async post(url: string, data: any): Promise<any> {
    return this.client?.post(url, data)
  }

  public async sse(url: string, onMessage: any, ctrl: AbortController): Promise<void> {
    return fetchEventSource(this.baseURL + url, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${useAuthorizationStore().token}`
      },
      signal: ctrl.signal,
      async onopen(response):Promise<void> {
        if (response) {
          if (response.status < 400) {
            return
          }
        }
        router.push({ path: '/login' }).finally()
        throw new Error();
      },
      onerror() {
      },
      onclose() {
      },
      onmessage(event) {
        onMessage(event)
      },
    })
  }
}

export const backendService: BackendService = new BackendService(
  import.meta.env.VITE_BACKEND_API_URL
)

export enum ResponseCode {
  /**
   * 成功
   */
  OK = 'OK',

  /**
   * 数据校验不通过，无效参数
   */
  METHOD_ARGUMENT_NOT_VALID = 'METHOD_ARGUMENT_NOT_VALID',

  /**
   * 服务器内部错误
   */
  INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR'
}
